/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.serviceapp.service.stores.impl;

import com.qinyeit.serviceapp.entity.*;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.service.materials.PurchaseSpecService;
import com.qinyeit.serviceapp.utils.CompuUtils;
import com.qinyeit.serviceapp.utils.SearchUtils;
import com.qinyetech.springstage.core.entity.search.Searchable;
import com.qinyetech.springstage.core.lang.QyMap;
import com.qinyetech.springstage.core.lang.StringUtils;
import com.qinyetech.springstage.core.repository.jdbc.PageNamedParameterJdbcTemplate;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.qinyetech.springstage.core.service.BaseService;
import com.qinyeit.serviceapp.repository.stores.StockRepository;
import com.qinyeit.serviceapp.service.stores.StockService;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/** 
 * ClassName: StockServiceImpl <br/> 
 * Function: 库存 业务实现 <br/> 
 * date: 2018-11-10 14:56:59 <br/> 
 * 
 * @author liuwenjin
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@Transactional
public class StockServiceImpl extends BaseService<Stock, Long> implements StockService {


	@Autowired
	private StockRepository stockRepository;
	@Autowired
	private PurchaseSpecService purchaseSpecService;
	@Autowired
	private PageNamedParameterJdbcTemplate jdbcTemplate;


	@Override
	public Stock getStocks(Long warehouseId, Long materialId, Long merchantGroupId) {
		Searchable searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
		searchable.addSearchParam("warehouseId_eq", warehouseId);
		searchable.addSearchParam("materialId_eq", materialId);
		Stock stock = this.findOne(searchable);
		return stock;
	}

	@Override
	public void saveStore(StoreInOrder storeInOrder, List<StoreInOrderDetail> detailList) {
		if (CollectionUtils.isEmpty(detailList)) {
			throw new BusinessRunTimeException("订单明细为空", 10001);
		}

		List<QyMap> list = new ArrayList<>();
		QyMap map = null; // 物料 、成本金额 、库存金额、数量
		String key = "";//M_物料id
		PurchaseSpec spec = null;
		Stock stock = null;
		double cost = 0.0;
		for (StoreInOrderDetail detail : detailList) {
			spec = purchaseSpecService.findById(detail.getSpecId());
			if(spec==null){
				throw new BusinessRunTimeException("商品采购规格不存在",20001);
			}
			stock = this.getStocks(storeInOrder.getWarehouseId(), spec.getMaterial().getId(), storeInOrder.getMerchantGroupId());
			if (stock != null) {
				//有库存 计算成本均价
				cost = (CompuUtils.add(
						CompuUtils.multiply(stock.getCount(), stock.getCost()),
						CompuUtils.multiply(detail.getStorageCount(), detail.getStoragePrice()
						))) / (CompuUtils.add(stock.getCount(), detail.getStorageCount()));
				stock.setCost(cost);
				stock.setCount(CompuUtils.add(stock.getCount(), detail.getStorageCount()));
				stock.setAmount(CompuUtils.add(stock.getAmount(), detail.getStorageTotal()));
			} else {
				stock = new Stock();
				stock.setWarehouseId(storeInOrder.getWarehouseId());
				stock.setMaterialId(spec.getMaterial().getId());
				stock.setMerchantGroupId(detail.getMerchantGroupId());
				stock.setCount(detail.getStorageCount());
				//总价/数量
				stock.setCost(CompuUtils.divide(detail.getStorageTotal(), detail.getStorageCount()));
				stock.setAmount(CompuUtils.multiply(stock.getCost(), stock.getCount()));
			}
			this.update(stock);
		}

	}

	@Override
	public List<Map<String, Object>> getStockList(Long merchantGroupId, Long warehouseId, Long materialId, String keywords,
												  Long categoryId,String flag,Long storeId) {
		String sql = "SELECT w.id AS warehouse_id, w.name AS warehouse_name, m.id, m.id AS material_id, m.no\n" +
				"\t, m.name, m.goods_spec, m.unit, m.category_id, m.state\n" +
				"\t, c.name AS category_name, s.count, s.cost, s.amount, s.merchant_group_id\n" +
				"\t, m.min_stock, m.max_stock, m.stocktake_type AS take_type, ds.name as store_name,ds.id as store_id,ds.industry " +
				"FROM stocks s\n" +
				"\tLEFT JOIN materials m ON s.material_id = m.id\n" +
				"\tLEFT JOIN warehouses w ON s.warehouse_id = w.id\n" +
				"\tLEFT JOIN material_categorys c ON m.category_id = c.id " +
				" LEFT JOIN dishes_stores ds on ds.id = m.store_id" +
				" WHERE s.merchant_group_id = :merchantGroupId\n" +
				"\tAND m.is_deleted = false ";
		QyMap map = QyMap.map("merchantGroupId",merchantGroupId);
		if(warehouseId!=null){
			sql += " and w.id = :warehouseId";
			map.setv("warehouseId",warehouseId);
		}if(materialId!=null){
			sql += " and m.id = :materialId";
			map.setv("materialId",materialId);
		}if(StringUtils.isNotBlank(keywords)){
			sql += " and (m.name like :name or m.no like :no or m.pinyin like :pinyin or m.spell like :spell)";
			map.setv("name",keywords);
			map.setv("no",keywords);
			map.setv("pinyin",keywords);
			map.setv("spell",keywords);
		}if (categoryId!=null){
			log.info("leibie : --- {}",categoryId);
			sql += " and (c.id=:categoryId or c.parent_ids like :categoryParentId)";
			map.setv("categoryId",categoryId);
			map.setv("categoryParentId","%/"+categoryId+"/%");
		}
		if (storeId!=null){
			sql += " and (ds.id = :storeId or ds.id is null)";
			map.setv("storeId",storeId);
		}
		List<Map<String,Object>> mapList = jdbcTemplate.queryForList(sql,map);

		if(StringUtils.isNotBlank(flag)){
			if("max".equals(flag)){
				//最大库存数量
				mapList = mapList.stream().filter(x->CompuUtils.compareTo(Double.valueOf(x.get("count").toString()),Double.valueOf(x.get("max_stock").toString()))==1).collect(Collectors.toList());
			}else if("min".equals(flag)){
				//最小库存数量
				mapList = mapList.stream().filter(x->CompuUtils.compareTo(Double.valueOf(x.get("count").toString()),Double.valueOf(x.get("max_stock").toString()))==-1).collect(Collectors.toList());
			}
		}

		return mapList;
	}

	@Override
	public List<Map<String,Object>> getWarehouses(Long materialId, Long merchantGroupId) {
		String sql = "SELECT s.cost, s.count, s.amount, s.material_id, s.warehouse_id\n" +
				"\t, w.name AS warehouse_name\n" +
				"FROM stocks s\n" +
				"\tLEFT JOIN warehouses w ON w.id = s.warehouse_id\n" +
				"WHERE s.is_deleted=0 and s.material_id = :materialId\n" +
				"\tAND s.merchant_group_id = :merchantGroupId";
		QyMap map = QyMap.map("materialId",materialId).setv("merchantGroupId",merchantGroupId);

		List<Map<String,Object>> list = jdbcTemplate.queryForList(sql,map);



		return list;
	}
}